using System;
using System.Collections.Generic;
using System.Text;
using Sandia.MVCFramework.Data;

namespace Sandia.MVCFramework.Data
{
    /// <summary>
    /// Simple generic that lets one encapsulate oject that makes it
    /// easy to pass around arbitrary objects through the system
    /// requiring IData.
    /// </summary>
    /// <remarks>
    /// This class is designed with the idea that it would not be used directly,
    /// but subclasses by specific implementations that would specify the type.
    /// That way, you can still use type information to differentiate different
    /// types of GenericIData impelmentations from one another.
    /// <p>The properties that expose the object stored are protected.  The
    /// subclass should expose the property as desired using a semantically
    /// meaningful name for what the object actually means.</p>
    /// </remarks>
    /// <typeparam name="T"></typeparam>
    public class GenericIData<T> : IData
    {
        /// <summary>
        /// The object to be stored
        /// </summary>
        private T obj;

        /// <summary>
        /// Create a new GenericIData object
        /// </summary>
        /// <param name="obj">The object to be stored.</param>
        public GenericIData(T obj)
        {
            this.obj = obj;
        }

        /// <summary>
        /// Accessor for the object to be stored.
        /// </summary>
        /// <remarks>
        /// In a subclass, expose this publicly as desired with a semantically meaningful name. (see the example)
        /// </remarks>
        protected T Obj
        {
            get { return obj; }
            set { obj = value; }
        }
    }

    /// <summary>
    /// Simple generic that allows two object of specified types to be stored and the
    /// package passed around as an IData object.
    /// </summary>
    /// <typeparam name="T">type of the first object to be stored</typeparam>
    /// <typeparam name="R">type of the second object to be stored</typeparam>
    public class GenericIData<T, R> : IData
    {
        /// <summary>
        /// the first object to be stored
        /// </summary>
        private T obj;

        /// <summary>
        /// The second object to be stored.
        /// </summary>
        private R obj2;

        /// <summary>
        /// Create a new GenericIData object
        /// </summary>
        /// <param name="obj">The first object</param>
        /// <param name="obj2">The second object</param>
        public GenericIData(T obj, R obj2)
        {
            this.obj = obj;
            this.obj2 = obj2;
        }

        /// <summary>
        /// Accessor for the first object.  
        /// </summary>
        /// <remarks>
        /// Expose publicly as desired in a sublcass with
        /// a semantically meaningful name.
        /// </remarks>
        protected T Obj
        {
            get { return obj; }
            set { obj = value; }
        }

        /// <summary>
        /// Accessor for the second object
        /// </summary>
        /// <remarks>
        /// Expose publicly as desired in a sublcass
        /// with a semantically meaninful name.
        /// </remarks>
        protected R Obj2
        {
            get { return obj2; }
            set { obj2 = value; }
        }
    }
}
